package component.fy.com.common_module.retrofit;

import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;


import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

import component.fy.com.common_module.base.BaseCommonApp;
import component.fy.com.common_module.base.ActivityManager;
import component.fy.com.common_module.constant.AppConstant;
import component.fy.com.common_module.bean.CheckResponseBean;
import component.fy.com.common_module.bean.CommonErrorBean;
import component.fy.com.common_module.utils.JsonUtil;
import component.fy.com.common_module.utils.LogUtil;
import component.fy.com.common_module.utils.SSLSocketClient;
import component.fy.com.common_module.utils.ToastUtil;
import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * Created by Administrator on 2017/10/17 0017.
 * 需要在Application中初始化
 */

public class RetrofitManager {
    private static final String TAG = "RetrofitManager";
    private static RetrofitManager retrofitManager;
    private static Retrofit retrofit;
    private static Context mContext;
    private static Handler handler = new Handler(Looper.getMainLooper());

    private RetrofitManager() {

    }

    public static RetrofitManager getInstance() {
        if (retrofitManager == null) {
            retrofitManager = new RetrofitManager();
        }
        return retrofitManager;
    }

    public void init(Context context) {
        mContext = context;
        retrofit = new Retrofit.Builder()
                .baseUrl(AppConstant.BaseUrl + "/")
                //String转化器
                .addConverterFactory(ScalarsConverterFactory.create())
//                gson转化器
//               .addConverterFactory(GsonConverterFactory.create())
                .client(getOkhttp())
                .build();
    }

    /**
     * 网络请求接口 的实例
     *
     * @return
     */
    private static RetrofitService getStringService() {
        RetrofitService service = retrofit.create(RetrofitService.class);
        return service;
    }

    /**
     * 配置OkHttpClient
     *
     * @return
     */
    private OkHttpClient getOkhttp() {
        File sdcache = mContext.getExternalCacheDir();//缓存地址
        int cacheSize = 10 * 1024 * 1024;//缓存大小
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .retryOnConnectionFailure(true)
                .sslSocketFactory(SSLSocketClient.getSSLSocketFactory())//获取这个SSLSocketFactory
                .hostnameVerifier(SSLSocketClient.getHostnameVerifier())
                .connectTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .readTimeout(15, TimeUnit.SECONDS)
//                .addInterceptor(new Interceptor() {
//                    @Override
//                    public okhttp3.Response intercept(Chain chain) throws IOException {
//                        Request request = chain.request()
//                                .newBuilder()
//                                .header("Content-Type", "application/json")
//                                .build();
////                        LogUtil.e("拦截器", "request:" + request.toString());
////                        LogUtil.e("拦截器", "request headers:" + request.headers().toString());
//                        return chain.proceed(request);
//                    }
//                })
                .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize))
                .build();
        return okHttpClient;
    }

    /**
     * 异步Get 无回调
     *
     * @param url
     */
    public static void doGet(String url) {
        Call<ResponseBody> mCall = getStringService().doGet(url);
        execute(ActivityManager.getInstance().currentVisibleActivity(), mCall);
    }

    /**
     * 异步Get 无回调
     *
     * @param header 动态header
     * @param url
     */
    public static void doGet(String header, String url) {
        Call<ResponseBody> mCall = getStringService().doGet(header, url);
        execute(ActivityManager.getInstance().currentVisibleActivity(), mCall);
    }

    /**
     * 异步Post 无回调
     *
     * @param url
     * @param requestBody
     */
    public static void doPost(String url, RequestBody requestBody) {
        Call<ResponseBody> mCall = getStringService().doPost(url, requestBody);
        execute(ActivityManager.getInstance().currentVisibleActivity(), mCall);
    }

    /**
     * 异步Post 无回调
     *
     * @param header     动态header
     * @param url
     * @param postString
     */
    public static void doPost(String header, String url, String postString) {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), postString);
        Call<ResponseBody> mCall = getStringService().doPost(header, url, requestBody);
        execute(ActivityManager.getInstance().currentVisibleActivity(), mCall);
    }

    /**
     * 异步Post 无回调
     *
     * @param url
     * @param postString
     */
    public static void doPost(String url, String postString) {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), postString);
        Call<ResponseBody> mCall = getStringService().doPost(url, requestBody);
        execute(ActivityManager.getInstance().currentVisibleActivity(), mCall);
    }

    /**
     * 异步上传图片 无回调
     *
     * @param header
     * @param url
     * @param pathList
     */
    public static void upLoadImages(String header, String url, List<String> pathList) {
        //        String token = "ASDDSKKK19990SDDDSS";//用户token
        MultipartBody.Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);//表单类型
//                .addFormDataPart(ParamKey.TOKEN, token);//ParamKey.TOKEN 自定义参数key常量类，即参数名
        //多张图片
        for (int i = 0; i < pathList.size(); i++) {
            File file = new File(pathList.get(i));//filePath 图片地址
            RequestBody imageBody = RequestBody.create(MediaType.parse("image/png"), file);//multipart/form-data image/png
            builder.addFormDataPart("image", file.getName(), imageBody);//"imgfile"+i 后台接收图片流的参数名
            LogUtil.e(TAG, "file.getName() = " + file.getName() + "是否存在 = " + file.exists());
        }
        List<MultipartBody.Part> parts = builder.build().parts();
        LogUtil.e(TAG, "上传图片数 = " + parts.size());
        Call<ResponseBody> mCall = getStringService().uploadImgs(header, url, parts);
        execute(ActivityManager.getInstance().currentVisibleActivity(), mCall);
    }

    /**
     * 执行异步  无回调
     *
     * @param call
     */
    private static void execute(final Activity activity, Call call) {
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, final Response<ResponseBody> response) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {//activity.isDestroyed()方法在api 17及以上才有效
                    if (activity == null || activity.isDestroyed() || activity.isFinishing()) {
                        LogUtil.e(TAG, "onResponse_界面已销毁");
                        return;
                    }
                } else {
                    if (activity == null || activity.isFinishing()) {
                        LogUtil.e(TAG, "onResponse_界面已销毁");
                        return;
                    }
                }
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            int code = response.code();
                            String message = response.message();
                            String bodyStr = response.body() == null ? "" : response.body().string();
                            String errorStr = response.errorBody() == null ? "" : response.errorBody().string();
//                            LogUtil.e(TAG, "请求返回结果:" + response + "\n==========header==========\n" + response.headers() + "\n==========header==========\n");
                            LogUtil.e(TAG, activity.getClass().getSimpleName() + "__返回结果：code = " + code + "\nmessage = " + message + "\nbodyStr = " + bodyStr + "\nerrorStr = " + errorStr);
                            if (code == 200) {
//                                LogUtil.e(ActivityManager.getInstance().currentActivity().getLocalClassName(), "返回结果：" + bodyStr);
                            } else {//不成功
                                CommonErrorBean errorBean = JsonUtil.parseJson(errorStr, CommonErrorBean.class);
                                LogUtil.e(TAG, activity.getClass().getSimpleName() + "__错误数据源errorBean = " + errorBean);
                                if (errorBean != null) {
                                    if (errorBean.getError().getCode() == 120) {//跳转登录界面
//                                        ARouter.getInstance().build(ARouterUtils.ARouter_Common_Login).navigation();
                                    }
                                }
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {//activity.isDestroyed()方法在api 17及以上才有效
                    if (activity == null || activity.isDestroyed() || activity.isFinishing()) {
                        LogUtil.e(TAG, "onFailure_界面已销毁");
                        return;
                    }
                } else {
                    if (activity == null || activity.isFinishing()) {
                        LogUtil.e(TAG, "onFailure_界面已销毁");
                        return;
                    }
                }
                t.printStackTrace();
                if (t.getMessage() != null) {
                    ToastUtil.showToast(t.getMessage().toString());
                }
            }
        });
    }

    /**
     * 异步Get 有回调
     *
     * @param url
     * @param resultCallback
     */
    public static void doGet(String url, final ResultCallback resultCallback) {
        Call<ResponseBody> mCall = getStringService().doGet(url);
        execute(ActivityManager.getInstance().currentVisibleActivity(), mCall, resultCallback);
    }

    /**
     * 异步Get 有回调
     *
     * @param header         动态header
     * @param url
     * @param resultCallback
     */
    public static void doGet(String header, String url, final ResultCallback resultCallback) {
        Call<ResponseBody> mCall = getStringService().doGet(header, url);
        execute(ActivityManager.getInstance().currentVisibleActivity(), mCall, resultCallback);
    }

    /**
     * 异步post 有回调
     *
     * @param url
     * @param requestBody
     */
    public static void doPost(String url, RequestBody requestBody, final ResultCallback resultCallback) {
        Call<ResponseBody> mCall = getStringService().doPost(url, requestBody);
        execute(ActivityManager.getInstance().currentVisibleActivity(), mCall, resultCallback);
    }

    /**
     * 异步Post 有回调
     *
     * @param header         动态header
     * @param url
     * @param postStr
     * @param resultCallback
     */
    public static void doPost(String header, String url, String postStr, ResultCallback resultCallback) {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), postStr);
        Call<ResponseBody> mCall = getStringService().doPost(header, url, requestBody);
        execute(ActivityManager.getInstance().currentVisibleActivity(), mCall, resultCallback);
    }

    /**
     * 异步post 有回调
     *
     * @param url
     * @param postStr
     */
    public static void doPost(String url, String postStr, ResultCallback resultCallback) {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), postStr);
        Call<ResponseBody> mCall = getStringService().doPost(url, requestBody);
        execute(ActivityManager.getInstance().currentVisibleActivity(), mCall, resultCallback);
    }

    /**
     * 异步上传图片 有回调
     *
     * @param header
     * @param url
     * @param pathList
     * @param resultCallback
     */
    public static void upLoadImages(String header, String url, List<String> pathList, ResultCallback resultCallback) {
//        String token = "ASDDSKKK19990SDDDSS";//用户token
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);//表单类型
//                .addFormDataPart(ParamKey.TOKEN, token);//ParamKey.TOKEN 自定义参数key常量类，即参数名
        //多张图片
        for (int i = 0; i < pathList.size(); i++) {
            File file = new File(pathList.get(i));//filePath 图片地址
            RequestBody imageBody = RequestBody.create(MediaType.parse("image/jpg"), file);//multipart/form-data
            builder.addFormDataPart("image", file.getName(), imageBody);//"imgfile"+i 后台接收图片流的参数名
            LogUtil.e(TAG, "图片名称 = " + file.getName() + "\n图片地址 = " + file.getPath());
        }
        List<MultipartBody.Part> parts = builder.build().parts();
        Call<ResponseBody> mCall = getStringService().uploadImgs(header, url, parts);
        execute(ActivityManager.getInstance().currentVisibleActivity(), mCall, resultCallback);
    }

    /**
     * 执行异步请求 有回调
     */
    private static void execute(final Activity activity, Call call, final ResultCallback resultCallback) {
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, final Response<ResponseBody> response) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {//activity.isDestroyed()方法在api 17及以上才有效
                    if (activity == null || activity.isDestroyed() || activity.isFinishing()) {
                        LogUtil.e(TAG, "onResponse_界面已销毁");
                        return;
                    }
                } else {
                    if (activity == null || activity.isFinishing()) {
                        LogUtil.e(TAG, "onResponse_界面已销毁");
                        return;
                    }
                }
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            resultCallback.onFinish();
                            int code = response.code();
                            String message = response.message();
                            String bodyStr = response.body() == null ? "" : response.body().string();
                            String errorStr = response.errorBody() == null ? "" : response.errorBody().string();
                            LogUtil.e(TAG, "code = " + code + ";message = " + message + "\nbody = " + bodyStr + "\nerrorBody = " + errorStr);

                            if (code == 200) {
                                LogUtil.e(activity.getClass().getSimpleName(), "返回结果:" + bodyStr);
                                if (TextUtils.isEmpty(bodyStr)) {//bodyStr为空
                                    LogUtil.e(activity.getClass().getSimpleName(), "没有返回结果===");
                                    resultCallback.onFailed("服务器没有数据返回");
                                    return;
                                }
                                if (JsonUtil.parseJson(bodyStr, resultCallback.mType) == null) {//解析出错
                                    resultCallback.onFailed("数据解析错误");
                                    LogUtil.e(activity.getClass().getSimpleName(), "数据解析异常");
                                } else {
                                    CheckResponseBean commonBean = JsonUtil.parseJson(bodyStr, CheckResponseBean.class);
                                    if (commonBean.isSuccess()) {//判定成功
                                        resultCallback.onResponse(JsonUtil.parseJson(bodyStr, resultCallback.mType));
                                    } else {//判定失败
                                        ToastUtil.showToast(commonBean.getError().getMessage());
                                        resultCallback.onFailed("");
                                    }
                                }
                            } else {//不成功
                                resultCallback.onFailed(message);
                                CommonErrorBean errorBean = JsonUtil.parseJson(errorStr, CommonErrorBean.class);
                                LogUtil.e(TAG, "errorBean = " + errorBean);
//                                LogUtil.e(TAG, "errorBean = " + errorBean + "\ncode = " + code + ";message = " + message + "\nbody = " + bodyStr + "\nerrorBody = " + errorStr);
                                if (errorBean != null) {
                                    ToastUtil.showToast(errorBean.getError().getMessage() + "");
                                    LogUtil.e(TAG, "网络报错数据解析不为空");
                                    if (errorBean.getError().getCode() == 120) {//跳转登录界面
//                                        ARouter.getInstance().build(ARouterUtils.ARouter_Common_Login).navigation();
                                    }
                                }
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                LogUtil.e(TAG, "网络连接问题");
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {//activity.isDestroyed()方法在api 17及以上才有效
                    if (activity == null || activity.isDestroyed() || activity.isFinishing()) {
                        LogUtil.e(TAG, "onFailure_界面已销毁");
                        return;
                    }
                } else {
                    if (activity == null || activity.isFinishing()) {
                        LogUtil.e(TAG, "onFailure_界面已销毁");
                        return;
                    }
                }
                resultCallback.onFinish();
                resultCallback.onError(call, t);
                /*if (!t.getMessage().toString().equals("Socket closed")) {
                    if (t.getMessage().toString().contains("Failed to connect to")) {
                        ToastUtil.showToast("请打开您的网络连接！");
                    } else {
                        ToastUtil.showToast(t.getMessage().toString());
                    }
                }*/
            }
        });
    }
}
